﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;

namespace MyHalconWindow
{
    public partial class MyHalconWindowControl: UserControl, MyHalcon.IShow
    {
        public HWindow mWindow;

        private List<MyRegion> mDrawRegionList = new List<MyRegion>();
        private List<MyContour> mMatchContoursList = new List<MyContour>();
        public MyHalconWindowControl()
        {
            InitializeComponent();
            mWindow = mHWindowControl.HalconWindow;
            mWinWidth = this.Size.Width;
            mWinHeight = this.Size.Height;
            mHWindowControl.Size = new Size(mWinWidth, mWinHeight);
            this.Disposed += new EventHandler(onDestroy);
        }

        private void button_tool_Click(object sender, EventArgs e)
        {
            panel_tool.Visible = true;
            panel_roi_tools.Visible = false;
        }


        #region 图像显示控制,放大，缩小，移动

        enum WinToolState
        {
            none, select, zoom_in, zoom_out, handmove, wheel,
            gen_rect1, gen_rect2, gen_circle, gen_ellipse
        };


        private WinToolState mWinToolState;
        private void hWindowControl_MouseDown(object sender, MouseEventArgs e)
        {
            switch (mWinToolState)
            {
                case WinToolState.select:
                    break;
                case WinToolState.zoom_in:
                    mWindow.ClearWindow();
                    zoom(1.05, (int)(e.X), (int)(e.Y));
                    reload_image();
                    break;
                case WinToolState.zoom_out:
                    mWindow.ClearWindow();
                    zoom(0.95, (int)(e.X), (int)(e.Y));
                    reload_image();
                    break;
                case WinToolState.handmove:
                    mMouseDown = true;
                    setMouseDownStatus(e.X, e.Y);
                    break;
                default:
                    break;
            }
        }

        private void hWindowControl_MouseMove(object sender, MouseEventArgs e)
        {
            switch (mWinToolState)
            {
                case WinToolState.select:

                    break;
                case WinToolState.zoom_in:

                    break;
                case WinToolState.zoom_out:
                    break;
                case WinToolState.handmove:
                    if (mMouseDown)
                    {
                        zoom_move(e.X, e.Y);
                        reload_image();
                    }
                    break;
                default:
                    break;

            }
        }

        private bool mMouseDown;
        private void hWindowControl_MouseUp(object sender, MouseEventArgs e)
        {
            switch (mWinToolState)
            {
                case WinToolState.select:
                case WinToolState.zoom_in:
                case WinToolState.zoom_out:
                case WinToolState.handmove:
                    mWindow.ClearWindow();
                    reload_image();
                    mMouseDown = false;
                    break;
                default:
                    break;

            }
        }

        private void hWindowControl_HMouseWheel(object sender, HMouseEventArgs e)
        {
            if (mWinToolState != WinToolState.wheel)
                return;
            double ratio = 1;
            if (e.Delta > 0)
            {
                ratio = 1.05;
            }
            else
            {
                ratio = 0.95;
            }
            zoom(ratio, (int)(e.X), (int)(e.Y));
            reload_image();
        }




        private void setWinToolState(WinToolState state)
        {
            mWinToolState = state;
            if (state != WinToolState.none) cb_none.Checked = false;
            if (state != WinToolState.zoom_in) cb_zoom_in.Checked = false;
            if (state != WinToolState.zoom_out) cb_zoom_out.Checked = false;
            if (state != WinToolState.handmove) cb_hand_move.Checked = false;
            if (state != WinToolState.wheel) cb_zoom_wheel.Checked = false;

            panel_tool.Visible = false;
        }


        

        private void cb_none_CheckedChanged_1(object sender, EventArgs e)
        {
            if (cb_none.Checked)
                setWinToolState(WinToolState.none);
        }

        private void cb_zoom_in_CheckedChanged_1(object sender, EventArgs e)
        {
            if (cb_zoom_in.Checked)
                setWinToolState(WinToolState.zoom_in);
        }

        private void cb_zoom_out_CheckedChanged_1(object sender, EventArgs e)
        {
            if (cb_zoom_out.Checked)
                setWinToolState(WinToolState.zoom_out);
        }

        private void cb_zoom_wheel_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_zoom_wheel.Checked)
            {
                mHWindowControl.Focus();
                setWinToolState(WinToolState.wheel);
            }
        }

        private void cb_hand_move_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_hand_move.Checked)
                setWinToolState(WinToolState.handmove);
        }

        private void cb_aspect_CheckedChanged(object sender, EventArgs e)
        {
            mWindow.ClearWindow();
            setWinToolState(WinToolState.none);
            zoom_fit_window();
            reload_image();
        }


        #endregion


        #region 画ROI
        private void btn_roi_tool_show_Click(object sender, EventArgs e)
        {
            panel_roi_tools.Visible = !panel_roi_tools.Visible;
            panel_tool.Visible = false;
        }


        #endregion


        


        public bool isEmpty(HObject hObj)
        {
            return (hObj == null || hObj.Key == IntPtr.Zero);
        }


        //private delegate void destoryDelegate();
        private void onDestroy(Object sender, EventArgs e)
        {
            if (!isEmpty(mHImage))
            {
                mHImage.Dispose();
            }
            if (mDrawRegionList.Count > 0)
            {
                foreach (MyRegion myRegion in mDrawRegionList)
                {
                    if (!isEmpty(myRegion.region)) myRegion.region.Dispose();
                }
                mDrawRegionList.Clear();
            }

            if (mMatchContoursList.Count > 0)
            {
                foreach (MyContour myContour in mMatchContoursList)
                {
                    if (!isEmpty(myContour.contour)) myContour.contour.Dispose();
                }
                mMatchContoursList.Clear();
            }
        }

        private void btn_draw_circle_Click(object sender, EventArgs e)
        {
            draw_circle();
            //panel_roi_tools.Visible = false;
        }

        private void btn_draw_ellipse_Click(object sender, EventArgs e)
        {
            draw_ellipse();
            //panel_roi_tools.Visible = false;
        }

        private void btn_draw_rect1_Click(object sender, EventArgs e)
        {
            draw_rect1();
            //panel_roi_tools.Visible = false;
        }

        private void btn_draw_rect2_Click(object sender, EventArgs e)
        {
            draw_rect2();
            //panel_roi_tools.Visible = false;
        }

        private void btn_draw_arbitrary_Click(object sender, EventArgs e)
        {
            draw_arbitrary();
            //panel_roi_tools.Visible = false;
        }

        private void btn_clear_all_roi_Click(object sender, EventArgs e)
        {
            clear_all_draw_regions();
            //panel_roi_tools.Visible = false;
        }

        private void MyHalconWindowControl_Resize(object sender, EventArgs e)
        {
            mWinWidth = this.Size.Width;
            mWinHeight = this.Size.Height;
            mHWindowControl.Size = new Size(mWinWidth, mWinHeight);
        }

        public HObject getCurrentImage()
        {
            return mHImage;
        }


        public void IShowImage(HObject img)
        {
            show_image(img);
        }

        public void IReloadImage()
        {
            reload_image();
        }

        public void IShowDrawRegion(HObject region, string color, bool isFill)
        {
            dispObj(region, color, isFill);
            HObject tempObj = null;
            HOperatorSet.CopyObj(region, out tempObj, 1, 1);

            //MyRegion myRegion = new MyRegion();
            //myRegion.region = tempObj;
            //myRegion.color = color;
            //myRegion.isFill = isFill;
            //mDrawRegionList.Add(myRegion);
        }

        public void IShowMatchContour(HObject contour, string color, bool isFill)
        {
            dispObj(contour, color, isFill);
            HObject tempObj = null;
            HOperatorSet.CopyObj(contour, out tempObj, 1, 1);

            MyContour myContour = new MyContour();
            myContour.contour = tempObj;
            myContour.color = color;
            myContour.isFill = isFill;
            mMatchContoursList.Add(myContour);

        }

        public void IClearAllDrawRegions()
        {
            clear_all_draw_regions();
        }

        public void IClearAllMatchContours()
        {
            clear_all_match_contours();
        }

        public void IShowText(string txt)
        {
            show_message(txt);
        }

        public void IClearAll()
        {
            clear_all_draw_regions();
            clear_all_match_contours();

        }

        public List<HObject> IGetDrawRegionList()
        {
            List<HObject> regionList = new List<HObject>();
            foreach(MyRegion myRegion in mDrawRegionList)
            {
                regionList.Add(myRegion.region);
            }
            return regionList;
        }

        public void IShowAllRegions()
        {
            foreach(MyRegion myRegion in mDrawRegionList)
            {
                dispObj(myRegion.region, myRegion.color, myRegion.isFill);
            }
        }

        public void IShowAllContours()
        {
            foreach (MyContour myContour in mMatchContoursList)
            {
                dispObj(myContour.contour, myContour.color, myContour.isFill);
            }
        }
    }


    public struct MyRegion
    {
        public HObject region { get; set; }
        public string name { get; set; }
        public string color { get; set; }
        public bool isFill { get; set; }
    }

    public struct MyContour
    {
        public HObject contour { get; set; }
        public string name { get; set; }
        public string color { get; set; }
        public bool isFill { get; set; }
    }




}
